home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
game
/
shoot
/
ADoom_src_1_1.lha
/
ADoom_src
/
amiga_ipx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-02-06
|
12KB
|
406 lines
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <dos.h>
#include <exec/exec.h>
#include <devices/sana2.h>
#include <proto/exec.h>
#include "i_system.h"
#include "amiga_ipx.h"
/**********************************************************************/
// This file isn't used in ADoom.
// It's rather buggy.
// It implements an crude IPX layer using any ethernet sana2 device.
// I wrote it out of frustration when I couldn't get amipx.library v1.0
// to work. Peter Mcgavin, 5 Feb 1998.
/**********************************************************************/
struct request {
struct MinNode node;
struct IPXECB *ecb;
struct IOSana2Req *io;
BOOL io_in_progress;
};
static struct MsgPort *sana2_mp = NULL;
static struct IOSana2Req *sana2_io = NULL;
static BOOL sana2_is_open = FALSE;
static UWORD the_socket = 0; /* we handle only one socket at a time */
static int the_packettype = 0;
static struct IPXAddress localaddress = {
{'\0', '\0', '\0', '\0'},
{'\0', '\0', '\0', '\0', '\0', '\0'},
0
};
static struct request *req_to_relinquish;
static struct MinList req_list; /* list of possibly outstanding requests */
/**********************************************************************/
static int ecb_length (struct IPXECB *ecb)
{
int i, len;
len = 0;
for (i = 0; i < ecb->FragCount; i++)
len += ecb->Fragment[i].FragSize;
return len;
}
/**********************************************************************/
static BOOL __asm __interrupt __saveds CopyFromBuff ( // send
register __a0 UBYTE *to,
register __a1 struct IPXECB *ecb,
register __d0 LONG n)
{
int i, len, rem;
struct IPXPacketHeader *ph;
ph = (struct IPXPacketHeader *)ecb->Fragment[0].FragData;
*to++ = 0xe0; /* Ethernet 802.2 3-byte header */
*to++ = 0xe0;
*to++ = 0x03;
n -= 3;
len = ecb_length (ecb);
if (n < len)
len = n;
*to++ = 0xff; /* checksum[0] */
*to++ = 0xff; /* checksum[1] */
*to++ = len >> 8; /* length[0] */
*to++ = len & 255; /* length[1] */
*to++ = ph->Tc;
*to++ = ph->Type;
memcpy (to, &ph->Dst, sizeof(struct IPXAddress));
to += sizeof(struct IPXAddress);
memcpy (to, &localaddress, sizeof(struct IPXAddress));
to += sizeof(struct IPXAddress);
n -= sizeof(struct IPXPacketHeader);
if (n > 0) {
rem = ecb->Fragment[0].FragSize - sizeof(struct IPXPacketHeader);
if (rem > 0) {
if (n < rem)
rem = n;
memcpy (to, &ecb->Fragment[0].FragData[sizeof(struct IPXPacketHeader)],
rem);
to += rem;
n -= rem;
}
for (i = 1; i < ecb->FragCount && n > 0; i++) {
rem = ecb->Fragment[i].FragSize;
if (n < rem)
rem = n;
memcpy (to, ecb->Fragment[i].FragData, rem);
to += rem;
n -= rem;
}
}
/* invoke ESR here */
ecb->InUse = 0;
return TRUE;
}
/**********************************************************************/
static BOOL __asm __interrupt __saveds CopyToBuff ( // get
register __a0 struct IPXECB *ecb,
register __a1 UBYTE *from,
register __d0 LONG n)
{
int i, rem;
from += 3; /* skip Ethernet 802.2 3-byte header */
n -= 3;
for (i = 0; i < ecb->FragCount && n > 0; i++) {
rem = ecb->Fragment[i].FragSize;
if (n < rem)
rem = n;
memcpy (ecb->Fragment[i].FragData, from, rem);
from += rem;
n -= rem;
}
memcpy (ecb->ImmedAddr,
((struct IPXPacketHeader *)ecb->Fragment[0].FragData)->Src.Node, 6);
/* invoke ESR here */
ecb->InUse = 0;
return TRUE;
}
/**********************************************************************/
/*
static BOOL __asm __interrupt __saveds PacketFilter (
register __a0 struct Hook *hook,
register __a2 struct IOSana2Req *ios2,
register __a1 APTR data)
{
return TRUE;
}
*/
/**********************************************************************/
void Init_IPX (char *sana2devicename, int unit, int packettype)
{
/*
int i;
static struct Hook packetfilterhook = {
{NULL},
(ULONG (*)())PacketFilter,
NULL,
NULL
};
*/
static struct TagItem ios2_tags[] = {
{S2_CopyToBuff, (ULONG)CopyToBuff},
{S2_CopyFromBuff, (ULONG)CopyFromBuff},
/*{S2_PacketFilter, (ULONG)&packetfilterhook},*/
{TAG_DONE, 0}
};
NewList ((struct List *)&req_list);
the_packettype = packettype;
if ((sana2_mp = CreatePort (NULL, 0)) == NULL ||
(sana2_io = (struct IOSana2Req *)CreateExtIO (sana2_mp,
sizeof(struct IOSana2Req))) == NULL)
I_Error ("Can't create port");
sana2_io->ios2_BufferManagement = ios2_tags;
if (OpenDevice (sana2devicename, unit, (struct IORequest *)sana2_io, 0) != 0)
I_Error ("Can't open %s, unit %d", sana2devicename, unit);
sana2_is_open = TRUE;
sana2_io->ios2_Req.io_Command = S2_CONFIGINTERFACE;
sana2_io->ios2_Req.io_Flags = 0; /* SANA2IOF_QUICK */
memset (sana2_io->ios2_SrcAddr, 0, SANA2_MAX_ADDR_BYTES);
DoIO ((struct IORequest *)sana2_io);
sana2_io->ios2_Req.io_Command = S2_GETSTATIONADDRESS;
DoIO ((struct IORequest *)sana2_io);
if (sana2_io->ios2_Req.io_Error != 0)
I_Error ("Error %d getting station address", sana2_io->ios2_Req.io_Error);
memcpy (localaddress.Node, sana2_io->ios2_SrcAddr,
sizeof(localaddress.Node));
/*
printf ("Source address =");
for (i = 0; i < SANA2_MAX_ADDR_BYTES; i++)
printf (" %02x", sana2_io->ios2_SrcAddr[i]);
printf ("\n");
printf ("Dest address =");
for (i = 0; i < SANA2_MAX_ADDR_BYTES; i++)
printf (" %02x", sana2_io->ios2_DstAddr[i]);
printf ("\n");
*/
}
/**********************************************************************/
void Shutdown_IPX (void)
{
struct request *req;
struct MinNode *succ;
if (sana2_is_open) {
/* abort and free outstanding requests */
req = (struct request *)req_list.mlh_Head;
succ = req->node.mln_Succ;
while (succ != NULL) {
if (req->io_in_progress) {
AbortIO ((struct IORequest *)req->io);
WaitIO ((struct IORequest *)req->io);
req->io_in_progress = FALSE;
req->ecb->InUse = 0;
}
DeleteExtIO ((struct IORequest *)req->io);
Remove ((struct Node *)&req->node);
FreeMem (req, sizeof(struct request));
req = (struct request *)succ;
succ = req->node.mln_Succ;
}
CloseDevice ((struct IORequest *)sana2_io);
sana2_is_open = FALSE;
}
if (sana2_io != NULL) {
DeleteExtIO ((struct IORequest *)sana2_io);
sana2_io = NULL;
}
if (sana2_mp != NULL) {
DeletePort (sana2_mp);
sana2_mp = NULL;
}
}
/**********************************************************************/
UWORD IPXOpenSocket (UWORD socketid)
{
if (the_socket != 0)
return 0;
the_socket = socketid;
localaddress.Socket = socketid;
return the_socket;
}
/**********************************************************************/
void IPXCloseSocket (UWORD socketid)
{
the_socket = 0;
}
/**********************************************************************/
int IPXGetLocalTarget (struct IPXAddress *request, UBYTE reply[6])
{
memcpy (reply, request->Node, 6);
return 1;
}
/**********************************************************************/
void IPXSendPacket (struct IPXECB *ecb)
{
struct request *req;
struct IPXPacketHeader *ph;
req = *(struct request **)ecb->IPXWork;
if (req == NULL) {
if ((req = (struct request *)AllocMem (sizeof(struct request),
MEMF_CLEAR)) == NULL ||
(req->io = (struct IOSana2Req *)CreateExtIO (sana2_mp,
sizeof(struct IOSana2Req))) == NULL)
I_Error ("Can't create port or IO");
*((struct request **)ecb->IPXWork) = req;
req->io_in_progress = FALSE;
*req->io = *sana2_io;
req->io->ios2_Req.io_Flags = 0; /* SANA2IOF_RAW | SANA2IOF_QUICK */
req->io->ios2_PacketType = the_packettype; /* 802.3 */ /* 0x8137 Novell */
/* 2049 Envoy IP, 2055 Envoy ARP */
req->ecb = ecb;
AddTail ((struct List *)&req_list, (struct Node *)&req->node);
} else if (req->io_in_progress) {
WaitIO ((struct IORequest *)sana2_io);